#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>

using namespace std;

char disp[24][80], simv;
bool fig_mas[5][5];
bool mas[24][80];

int new_fig, klav, figx, figy, step, height, width;

void f_disp();
void f_new();
void f_sdvig(int napr);
void f_fig();
bool f_if();
void f_prov();
void f_smesh(int str);
void f_pov();
bool f_menu();
char f_simv();
//bool f_go_prov():


int main()
{
    height = 15;
    width = 20;
    simv = 4;
    setlocale(LC_ALL, "");
    if (f_menu()) return 0;
    for (int i=0; i<height; i++)
    {
        for (int ii=0; ii<width; ii++)
        {
            mas[i][ii] = 0;
        }
    }

    step = 0;
    figx = 0;
    figy = 0;

    f_new();

    while(1)
    {
///////////////////////////////////////////////////////////////////
        for (int i=0; i<height; i++)
        {
            for (int ii=0; ii<width; ii++)
            {
                disp[i][ii] = ' ';
            }
            disp[i][width+1] = '\n';
        }
///////////////////////////////////////////////////////////////////
        f_fig();

        step++;
        if (step > 10)
        {
            step = 0;
            f_sdvig(0); // сдвиг вниз каждый шаг
        }
        Sleep(60);

        if(kbhit())
        {
            klav = getch();
            switch (klav)
            {
            case 27:
                if (f_menu()) return 0;
                break;
            case 72:
                f_pov();
                break;
            case 75:
                f_sdvig(2);
                break;
            case 77:
                f_sdvig(1);
                break;
            case 80:
                f_sdvig(0);
                break;
            }
        }
//////////////////////////////////////////////////////////////////////
        f_fig();
        for (int i=0; i<height; i++) // вертикальная граница
        {
            mas[i][0] = 1;
            mas[i][width-1] = 1;
        }

        for (int i=0; i<width-1; i++) // горизонтальная граница
        {
            //mas[0][i] = 1;
            mas[height-1][i] = 1;
        }

        system("cls");
        f_disp();
    }
    return 0;
}

void f_disp()
{
    for (int i=0; i<height; i++)
    {
        wcout << disp[i] << L'\n';
    }
}

void f_new() // Создание новой фигуры
{
    f_prov();

    new_fig = rand()%4;

    for (int i=0; i<6 ;i++) // убрать цикл
    {
        for (int ii; ii<6 ;ii++)
        {
            fig_mas[i][ii] = 0;
        }
    }

    switch(new_fig)
    {
    case 0: // Т-образная фигура
        fig_mas[0][0]=0;fig_mas[1][0]=0;fig_mas[2][0]=0;fig_mas[3][0]=0;fig_mas[4][0]=0;
        fig_mas[0][1]=0;fig_mas[1][1]=0;fig_mas[2][1]=1;fig_mas[3][1]=0;fig_mas[4][1]=0;
        fig_mas[0][2]=0;fig_mas[1][2]=1;fig_mas[2][2]=1;fig_mas[3][2]=1;fig_mas[4][2]=0;
        fig_mas[0][3]=0;fig_mas[1][3]=0;fig_mas[2][3]=0;fig_mas[3][3]=0;fig_mas[4][3]=0;
        fig_mas[0][4]=0;fig_mas[1][4]=0;fig_mas[2][4]=0;fig_mas[3][4]=0;fig_mas[4][4]=0;
        break;

    case 1: // Палка
        fig_mas[0][0]=0;fig_mas[1][0]=0;fig_mas[2][0]=0;fig_mas[3][0]=0;fig_mas[4][0]=0;
        fig_mas[0][1]=0;fig_mas[1][1]=0;fig_mas[2][1]=0;fig_mas[3][1]=0;fig_mas[4][1]=0;
        fig_mas[0][2]=1;fig_mas[1][2]=1;fig_mas[2][2]=1;fig_mas[3][2]=1;fig_mas[4][2]=1;
        fig_mas[0][3]=0;fig_mas[1][3]=0;fig_mas[2][3]=0;fig_mas[3][3]=0;fig_mas[4][3]=0;
        fig_mas[0][4]=0;fig_mas[1][4]=0;fig_mas[2][4]=0;fig_mas[3][4]=0;fig_mas[4][4]=0;
        break;

    case 2: // Г-образная фигура
        fig_mas[0][0]=0;fig_mas[1][0]=0;fig_mas[2][0]=0;fig_mas[3][0]=0;fig_mas[4][0]=0;
        fig_mas[0][1]=0;fig_mas[1][1]=1;fig_mas[2][1]=0;fig_mas[3][1]=0;fig_mas[4][1]=0;
        fig_mas[0][2]=0;fig_mas[1][2]=1;fig_mas[2][2]=1;fig_mas[3][2]=1;fig_mas[4][2]=0;
        fig_mas[0][3]=0;fig_mas[1][3]=0;fig_mas[2][3]=0;fig_mas[3][3]=0;fig_mas[4][3]=0;
        fig_mas[0][4]=0;fig_mas[1][4]=0;fig_mas[2][4]=0;fig_mas[3][4]=0;fig_mas[4][4]=0;
        break;

    default: // точечка :3
        fig_mas[0][0]=0;fig_mas[1][0]=0;fig_mas[2][0]=0;fig_mas[3][0]=0;fig_mas[4][0]=0;
        fig_mas[0][1]=0;fig_mas[1][1]=0;fig_mas[2][1]=0;fig_mas[3][1]=0;fig_mas[4][1]=0;
        fig_mas[0][2]=0;fig_mas[1][2]=0;fig_mas[2][2]=1;fig_mas[3][2]=0;fig_mas[4][2]=0;
        fig_mas[0][3]=0;fig_mas[1][3]=0;fig_mas[2][3]=0;fig_mas[3][3]=0;fig_mas[4][3]=0;
        fig_mas[0][4]=0;fig_mas[1][4]=0;fig_mas[2][4]=0;fig_mas[3][4]=0;fig_mas[4][4]=0;
        break;
    }
    figx = width/2-3;
    figy = 0;

    for (int i=0; i<5; i++)
    {
        for (int ii=0; ii<5; ii++)
            if (fig_mas[i][ii] == 1)
                disp[i+figy][ii+figx] = simv;

    }
}

void f_fig()
{
    for (int i=0; i<5; i++)
    {
        for (int ii=0; ii<5; ii++)
        {
            if (fig_mas[i][ii] == 1)
                disp[i+figy][ii+figx] = simv;
        }
    }

    for (int i=0; i<height; i++)
    {
        for (int ii=0; ii<width; ii++)
        {
            if (mas[i][ii] == 1)
                disp[i][ii] = simv;
        }
    }
}

void f_sdvig(int napr)
{
    switch (napr)
    {
    case 0:
        figy++;
        if (f_if())
        {
            figy--;
            for (int i=0; i<5; i++)
            {
                for (int ii=0; ii<5; ii++)
                {
                    if (fig_mas[i][ii] == 1)
                    {
                        mas[i+figy][ii+figx] = 1;
                    }
                }
            }
            figy=0;
            f_new();
        }
        break;

    case 1:
        figx++;
        if (f_if())
        {
            figx--;
        }
        break;

    case 2:
        figx--;
        if (f_if())
        {
            figx++;
        }
        break;
    };
    for (int i=0; i<height; i++)
    {
        for (int ii=0; ii<width; ii++)
        {
            disp[i][ii] = ' ';
        }
        disp[i][width+1] = '\n';
    }
}

bool f_if()
{
    bool result = 0;
    for (int i=0; i<5; i++)
    {
        for (int ii=0; ii<5; ii++)
        {
            if ((fig_mas[i][ii] == mas[i+figy][ii+figx]) && (fig_mas[i][ii] == 1))
            {
                result = 1;
            }
        }
    }
    return result;
}

void f_prov()
{
    bool r;
    int str;
    for (int i=1; i<height-1; i++)
    {
        r = 1;
        for (int ii=1; ii<width-1; ii++)
        {

            if (mas[i][ii] == 0)
            {
                r = 0;
            }

        }
        if (r == 1)
        f_smesh(i);
    }
}

void f_smesh(int str)
{
    char i = 51;
    while (i>47)
    {
        for (int ii=1; ii<width-1; ii++)
        {
            disp[str][ii] = i;
        }
        i--;
        system("cls");
        f_disp();
        Sleep(200);

    }




    for (int i=str; i>1; i--)
    {
        for (int ii=1; ii<width-1; ii++)
        {
            mas[i][ii] = mas[i-1][ii];
        }
    }
}

void f_pov()
{
    if (new_fig < 4)
    {
        int vremen = fig_mas[2][1];
        fig_mas[2][1] = fig_mas[1][2];
        fig_mas[1][2] = fig_mas[2][3];
        fig_mas[2][3] = fig_mas[3][2];
        fig_mas[3][2] = vremen;

        vremen = fig_mas[2][0];
        fig_mas[2][0] = fig_mas[0][2];
        fig_mas[0][2] = fig_mas[2][4];
        fig_mas[2][4] = fig_mas[4][2];
        fig_mas[4][2] = vremen;

        vremen = fig_mas[1][1];
        fig_mas[1][1] = fig_mas[1][3];
        fig_mas[1][3] = fig_mas[3][3];
        fig_mas[3][3] = fig_mas[3][1];
        fig_mas[3][1] = vremen;

        if (f_if())
        {
            vremen = fig_mas[2][1];
            fig_mas[2][1] = fig_mas[3][2];
            fig_mas[3][2] = fig_mas[2][3];
            fig_mas[2][3] = fig_mas[1][2];
            fig_mas[1][2] = vremen;

            vremen = fig_mas[2][0];
            fig_mas[2][0] = fig_mas[4][2];
            fig_mas[4][2] = fig_mas[2][4];
            fig_mas[2][4] = fig_mas[0][2];
            fig_mas[0][2] = vremen;

            vremen = fig_mas[1][1];
            fig_mas[1][1] = fig_mas[3][1];
            fig_mas[3][1] = fig_mas[3][3];
            fig_mas[3][3] = fig_mas[1][3];
            fig_mas[1][3] = vremen;
        }
    }
    system("cls");
    f_disp();
}

bool f_menu()
{
    bool s = 1;
    int n = 1;
    char sim = 16;

    while(s)
    {
        if(kbhit())
        {
            klav = getch();
            switch (klav)
            {
            case 13:
                switch(n)
                {
                    case 1:
                        for (int i=0; i<height; i++)
                        {
                            for (int ii=0; ii<width; ii++)
                            {
                                mas[i][ii] = 0;
                            }
                        }

                        step = 0;
                        figx = 0;
                        figy = 0;

                        f_new();
                        return 0;
                        break;

                    case 2:
                        return 0;
                        break;

                    case 3:
                        system("cls");
                        wcout << L"УПРАВЛЕНИЕ: \n";
                        wcout << L"стрелки - передвижение \n";
                        wcout << L"Esc - меню \n";
                        wcout << L" \n";
                        wcout << L"Автор: \n";
                        wcout << L"Лис :3 \n";
                        wcout << L" \n";
                        wcout << L"Для возврата нажмите любую клавишу... \n";
                        getch();
                        system("cls");
                        wcout << L" Новая игра \n";
                        wcout << L" Продолжить \n";
                        break;

                    case 4:
                        simv = f_simv();
                        break;

                    case 5:
                        system("cls");
                        wcout << L"Прошу прощения, но тут мне лень " << '\n';
                        wcout << L"было делать проверку, так что " << '\n';
                        wcout << L"прошу вводить нормальные числа...  " << '\n';
                        wcout << L'\n';
                        wcout << L"Ширина: " << width << '\n';
                        wcout << L"Новое значение: ";
                        cin >> width;
                        wcout << L" \n";
                        wcout << L"Высота: " << height << '\n';
                        wcout << L"Новое значение: ";
                        cin >> height;
                        wcout << L" \n";

                        for (int i=0; i<height; i++)
                        {
                            for (int ii=0; ii<width; ii++)
                            {
                                mas[i][ii] = 0;
                            }
                        }

                        step = 0;
                        figx = 0;
                        figy = 0;

                        f_new();

                        wcout << L"Сохранено... \n";
                        Sleep(1000);
                        system("cls");
                        wcout << L" Новая игра \n";
                        wcout << L" Продолжить \n";
                        wcout << L" Об игре \n";
                        wcout << L" Символ заполнения: " << simv << '\n';
                        break;

                    case 6:
                        return 1;
                        break;
                }
                break;
            case 72:
                if (n > 1) n--;
                break;
            case 80:
                if (n < 6) n++;
                break;
            }
        }
        system("cls");
        if (n == 1)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Новая игра \n";

        if (n == 2)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Продолжить \n";

        if (n == 3)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Об игре \n";

        if (n == 4)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Символ заполнения: " << simv << '\n';

        if (n == 5)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Ширина: " << width << L"; Высота: " << height << '\n';

        if (n == 6)
            cout << sim;
        else
            cout << ' ';
        wcout << L"Выход\n";
        Sleep(32);
        rand();
    }
}

char f_simv()
{
    bool s = 1;
    int n = simv;
    char sim = 16;
    char simvol;

    while(s)
    {
        if(kbhit())
        {
            klav = getch();
            switch (klav)
            {
            case 13:
                return n;
                break;
            case 72:
                if (n > 1) n--;
                break;
            case 80:
                if (n < 6) n++;
                break;
            }
        }
        system("cls");
        if (n == 1)
            cout << sim;
        else
            cout << ' ';
        simvol = 1;
        wcout <<  simvol << '\n';

        if (n == 2)
            cout << sim;
        else
            cout << ' ';
        simvol = 2;
        wcout <<  simvol << '\n';

        if (n == 3)
            cout << sim;
        else
            cout << ' ';
        simvol = 3;
        wcout <<  simvol << '\n';

        if (n == 4)
            cout << sim;
        else
            cout << ' ';
        simvol = 4;
        wcout <<  simvol << '\n';

        if (n == 5)
            cout << sim;
        else
            cout << ' ';
        simvol = 5;
        wcout <<  simvol << '\n';

        if (n == 6)
            cout << sim;
        else
            cout << ' ';
        simvol = 6;
        wcout <<  simvol << '\n';
        Sleep(32);
        rand();
    }
}
